package com.citywithincity.api.utils;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import com.citywithincity.api.IFileReader;
import com.citywithincity.utils.JsonUtil;
import com.citywithincity.utils.MD5Util;

public class SignUtil {

	public static String sign(Map<String, Object> json,String key){
		StringBuilder sb = new StringBuilder();
		getString(json, sb);
		sb.append(key);
		return MD5Util.md5Appkey(sb.toString());
	}
	
	public static String result(Object value,String key,String bsId){
		//商户id,rand_str,time,sign,result
		Map<String, Object> map = new TreeMap<String,Object>();
		map.put("flag", 0);
		map.put("result", value);
		map.put("bsId", bsId);
		map.put("rand_str", MD5Util.md5Appkey(String.valueOf(System.nanoTime() * Math.random())));
		map.put("time", System.currentTimeMillis()/ 1000);
		
		StringBuilder sb = new StringBuilder();
		mapToString(map, sb);
		sb.append(key);
		map.put("sign", MD5Util.md5Appkey(sb.toString()));
		
		return JsonUtil.toJson(map);
	}
	
	@SuppressWarnings("unchecked")
	private static void getString(Object value,StringBuilder sb){
		if(value instanceof Map){
			getString((Map<String, Object>)value, sb);
		}else if(value instanceof byte[]) {
			sb.append("null");
		}else{
			sb.append(value);
		}
	}
	
	private static void getString(Map<String, Object> json,StringBuilder sb){
		//这里开始签名
    	Map<String,Object> map = new TreeMap<String,Object>();
    	for (Entry<String, Object> entry : json.entrySet()) {
			Object value = entry.getValue();
			if(value instanceof IFileReader){
				continue;
			}
			if(value instanceof HttpServletRequest){
				continue;
			}
			if(value instanceof byte[]){
				value = null;
			}
			
			String key = entry.getKey();
			map.put(key, value);
		}
    	mapToString(map, sb);
	}
	
	@SuppressWarnings("unchecked")
	private static void mapToString(Map<String,Object> map ,StringBuilder sb){
		for (Entry<String, Object> entry : map.entrySet()) {
			Object value = entry.getValue();
			if(value instanceof List){
				sb.append(entry.getKey());
				getString((List<Object>)value,sb);
			}else{
				sb.append(entry.getKey()).append(value);
			}
		}
	}
	
	private static void getString(List<Object> json,StringBuilder sb){
		for(int i=0, count = json.size(); i < count; ++i){
			getString(json.get(i), sb);
		}
	}
	
	public static boolean verifyBusiness(Map<String, Object> json, String key){
		String sign = (String)json.get(ApiUtil.sign);
		if(sign==null){
			return false;
		}
		json.remove("sign");
		if(!json.containsKey(ApiUtil.rand_str)){
			return false;
		}
		if(!json.containsKey(ApiUtil.time)){
			return false;
		}
		return sign.equals(SignUtil.sign(json,key));
	}

	public static boolean verify(Map<String, Object> json, String key) {
		String sign = (String)json.get(ApiUtil.sign);
		if(sign==null){
			return false;
		}
		if(!json.containsKey(ApiUtil.deviceID)){
			return false;
		}
		json.remove("sign");
		if(!json.containsKey(ApiUtil.rand_str)){
			return false;
		}
		if(!json.containsKey(ApiUtil.time)){
			return false;
		}
		
		return sign.equals(SignUtil.sign(json,key));
	}
}
